package com.lx.screenshot.util;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.graphics.Bitmap;
import android.graphics.PixelFormat;
import android.graphics.drawable.Drawable;
import android.hardware.display.DisplayManager;
import android.hardware.display.VirtualDisplay;
import android.media.Image;
import android.media.ImageReader;
import android.media.projection.MediaProjection;
import android.media.projection.MediaProjectionManager;
import android.os.IBinder;
import android.os.SystemClock;
import android.util.DisplayMetrics;
import android.view.WindowManager;
import android.widget.Toast;

import androidx.annotation.Nullable;

import com.lx.screenshot.databinding.TranslationFragmentBinding;
import com.lx.screenshot.floatWindow.FloatWindow;
import com.lx.screenshot.floatWindow.OnScreenResult;
import com.lx.screenshot.floatWindow.ResultWindow;
import com.lx.screenshot.service.floatWindowService.FloatWindowService;
import com.lx.screenshot.service.floatWindowService.ServiceBinder;



import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;

/**
 * 截图的工具类
 * 使用步骤：1、申请权限；2、在onActivityResult中调用对应的方法；3、想截屏时调用screen截屏
 */
public class ScreenShotUtil {
    private static final int REQUEST_SCREEN_PERMISSION_CODE = 0x166;
    private static final int REQUEST_FLOAT_PERMISSION_CODE = 0x167;
    private static final String SCREEN_MEDIA_PROJECT_NAME = "screen_project";
    private static Context mActivity;
    private static MediaProjectionManager manage;
    private static ImageReader imageReader;
    public static String imgPath;
    private static DisplayMetrics metrics;
    private static VirtualDisplay virtualDisplay;
    private static boolean hasPermission = false;
    private static MediaProjection mediaProjection;

    private static Intent floatWinServiceIntent;
    private static ServiceBinder floatWinServiceBinder;
    private static ServiceConnection floatWinServiceCon;

    public static  boolean isScreenArea = false;

    static class ScreenRecordHolder {
        private static ScreenShotUtil instance = new ScreenShotUtil();
    }

    private ScreenShotUtil() {}
    public static ScreenShotUtil getInstance() {
        return ScreenRecordHolder.instance;
    }

    public static void init(Context activity) {
        ScreenShotUtil.mActivity = activity;
        startFloatWindowService();
    }
    private static void startFloatWindowService() {

        floatWinServiceIntent = new Intent(mActivity, FloatWindowService.class);
        floatWinServiceCon = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                floatWinServiceBinder = (ServiceBinder) service;
//                // 绑定服务成功，就更新图标
//                // 设置查询失败时的回调事件
//                ResultWindow.setOnPostFailure(()->{
//                    // 重启悬浮窗
//                    FloatWindow window = floatWinServiceBinder.getFloatWindow();
//                    window.destroyResultWin();
//                    window.destroy();
//                    window.createWithNoReChooseArea();
//                });
            }

            @Override
            public void onServiceDisconnected(ComponentName name) {
//                Log.d(TAG, "onServiceDisconnected: floatWinService创建失败");
            }
        };

        if (!ServiceUtil.isRunning(mActivity, FloatWindowService.class.getName())) {
            mActivity.startService(floatWinServiceIntent);
        }
        mActivity.bindService(floatWinServiceIntent, floatWinServiceCon, Service.BIND_AUTO_CREATE);
    }

    public static void creatCaptureButton() {
        FloatWindow window = floatWinServiceBinder.getFloatWindow();
//            Log.d(TAG, "addListener: floatWin running = "+window.isRunning()+", created = "+window.isCreated());
        // 现在是隐藏，就显示
        if (window.isCreated() && !window.isRunning()) {
            window.show();
            return;
        }
        // 现在没有被创建，就创建
        if (!window.isCreated()) {
            window.setOnScreenResult(new OnScreenResult() {
                @Override
                public void screenSuccess(Bitmap bitmap) {
                    Bitmap bitmap1 = ScreenShotUtil.screen();
                    if(bitmap != null){
                        onScreenResult.screenSuccess(bitmap1);
                    }
                }
            });
            //启动授权页面
            window.createWithPermissionCheck(mActivity);
            return;
        }
        // 现在已经显示，就销毁
        if (window.isRunning()) {
            window.destroyResultWin();
            window.destroy();
            hasPermission = false;
            if(mediaProjection != null) mediaProjection.stop();
        }
    }
    public static void save(Bitmap bitmap) {
        File file = new File(imgPath);
        try {
            FileOutputStream out = new FileOutputStream(file);
            // 写入时覆盖原文件
//            boolean deleted = false;
//            if (file.exists()) {
//                deleted = file.delete();
//            }
//            if (deleted || !file.exists())
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
            out.flush();
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static boolean isHasPermission() {
        return hasPermission;
    }

    public static Bitmap screen(float startX, float startY, float endX, float endY) {
        Bitmap bitmap = screen();
        // 截取指定区域
        if (bitmap != null) {
            int w = bitmap.getWidth();
            int h = bitmap.getHeight();
            bitmap = Bitmap.createBitmap(bitmap, Math.round(startX / metrics.widthPixels * w), Math.round(startY),
                    Math.round((endX - startX) / metrics.widthPixels * w), Math.round(endY - startY));
        }
        return bitmap;
    }
    public static Bitmap screen(Bitmap bitmap, float startX, float startY, float endX, float endY) {
        // 截取指定区域
        if (bitmap != null) {
            int w = bitmap.getWidth();
            int h = bitmap.getHeight();
            bitmap = Bitmap.createBitmap(bitmap, Math.round(startX / metrics.widthPixels * w), Math.round(startY),
                    Math.round((endX - startX) / metrics.widthPixels * w), Math.round(endY - startY));
        }
        return bitmap;
    }
    public static Bitmap screen() {
        // 更新值，避免转屏
        updateVar();
        Bitmap bitmap = null;
        virtualDisplay = mediaProjection.createVirtualDisplay(
                SCREEN_MEDIA_PROJECT_NAME, metrics.widthPixels, metrics.heightPixels,
                metrics.densityDpi, DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
                imageReader.getSurface(), null, null
        );

        Image image = imageReader.acquireLatestImage();
        while (image == null) {
            SystemClock.sleep(100);
            image = imageReader.acquireLatestImage();
        }
        Image.Plane[] planes = image.getPlanes();
        if (planes.length > 0) {
            ByteBuffer buffer = planes[0].getBuffer();
            int d = buffer.remaining(); //图片大小
            //每个像素的间距
            int pixelStride = planes[0].getPixelStride();
            //总的间距
            int rowStride = planes[0].getRowStride();
            int rowPadding = rowStride - pixelStride * metrics.widthPixels;
            bitmap = Bitmap.createBitmap(metrics.widthPixels + rowPadding / pixelStride, metrics.heightPixels, Bitmap.Config.ARGB_8888);
            bitmap.copyPixelsFromBuffer(buffer);
        }
        image.close();
        virtualDisplay.release();
        virtualDisplay = null;
        return bitmap;
    }

    public static void syncScreen(){
        // 更新值，避免转屏
        updateVar();
        Bitmap bitmap = null;
        virtualDisplay = mediaProjection.createVirtualDisplay(
                SCREEN_MEDIA_PROJECT_NAME, metrics.widthPixels, metrics.heightPixels,
                metrics.densityDpi, DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
                imageReader.getSurface(), null, null
        );

        Image image = null;
        while (image == null) {
            SystemClock.sleep(100);
            image = imageReader.acquireLatestImage();
        }
        Image.Plane[] planes = image.getPlanes();
        if (planes.length > 0) {
            ByteBuffer buffer = planes[0].getBuffer();
            int d = buffer.remaining(); //图片大小
            //每个像素的间距
            int pixelStride = planes[0].getPixelStride();
            //总的间距
            int rowStride = planes[0].getRowStride();
            int rowPadding = rowStride - pixelStride * metrics.widthPixels;
            bitmap = Bitmap.createBitmap(metrics.widthPixels + rowPadding / pixelStride, metrics.heightPixels, Bitmap.Config.ARGB_8888);
            bitmap.copyPixelsFromBuffer(buffer);
        }
        image.close();
        virtualDisplay.release();
        virtualDisplay = null;
        onScreenResult.screenSuccess(bitmap);
    }

    @SuppressLint("WrongConstant")
    private static void updateVar() {
        ((WindowManager) mActivity.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getRealMetrics(metrics);
        int w = metrics.widthPixels;
        int h = metrics.heightPixels;

        imageReader = ImageReader.newInstance(w, h, PixelFormat.RGBA_8888, 1);
    }

    public static void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        if (requestCode == REQUEST_SCREEN_PERMISSION_CODE)
            if (resultCode == Activity.RESULT_OK) {
                hasPermission = true;
                initMediaProjection(resultCode, data);
            } else {
                Toast.makeText(mActivity, "授权失败", Toast.LENGTH_SHORT).show();
            }
    }

    public static void onActivityResult(int requestCode, int resultCode, @Nullable Intent data, ServiceBinder binder, TranslationFragmentBinding binding) {
        if (resultCode == Activity.RESULT_OK) {
            if (requestCode == REQUEST_SCREEN_PERMISSION_CODE) {
                hasPermission = true;
                initMediaProjection(resultCode, data);
                SystemClock.sleep(200);

                // 创建悬浮窗
                floatWinServiceBinder.getFloatWindow().startCapture();
//                // 更改UI
//                binding.startTransBT.setImageResource(R.drawable.start_icon_green);
            }else if (requestCode == REQUEST_FLOAT_PERMISSION_CODE) {
                floatWinServiceBinder.getFloatWindow().create();
            }else{
                    Toast.makeText(mActivity, "授权失败", Toast.LENGTH_SHORT).show();
            }
        }
    }

    private static void initMediaProjection(int resultCode, Intent data) {
        initDisplay();
        mediaProjection = manage.getMediaProjection(resultCode, data);
    }

    @SuppressLint("WrongConstant")
    private static void initDisplay() {
        metrics = new DisplayMetrics();
        ((WindowManager) mActivity.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getRealMetrics(metrics);
        int w = metrics.widthPixels;
        int h = metrics.heightPixels;

        manage = (MediaProjectionManager) mActivity.getSystemService(Context.MEDIA_PROJECTION_SERVICE);
        imageReader = ImageReader.newInstance(w, h, PixelFormat.RGBA_8888, 2);

        imgPath = mActivity.getFilesDir().getAbsolutePath() + File.separator + "image.png";
    }

    private static OnScreenResult onScreenResult;
    public void setOnScreenResultLinster(OnScreenResult onScreenResult){
        this.onScreenResult = onScreenResult;
    }

    private ScreenShotUtil(Builder builder) {
        this.onScreenResult = builder.onScreenResult;
        creatCaptureButton();
    }

    /**
     * 用来构造menu的对象
     */
    public static final class Builder {

        private static OnScreenResult onScreenResult;
//        public Builder creatCaptureButton() {
//            ScreenShotUtil.creatCaptureButton();
//            return this;
//        }
        public Builder(){}

        public ScreenShotUtil showOnScreenResultLinster(OnScreenResult onScreenResult){
            this.onScreenResult = onScreenResult;
            return new ScreenShotUtil(this);
        }
    }

}
